package br.usp.ime.mac.mico.models.tests;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import br.usp.ime.mac.mico.models.Box;
import br.usp.ime.mac.mico.models.Place;
import br.usp.ime.mac.mico.models.Sample;
import junit.framework.TestCase;

public class BoxTest extends TestCase {

	//Instances used for testing.
	Box boxOne;
	Box boxTwo;

	//Attributes used for test instances.
	String boxOneFreezer = "freezer 1";
	String boxTwoFreezer = "freezer 2";
	String boxOneShelf   = "shelf 1";
	String boxTwoShelf   = "shelf 2";
	Sample sampleOne     = new Sample("sample 1");
	Sample sampleTwo     = new Sample("sample 2");

	@Override
	public void setUp() {
		boxOne = new Box();
		boxTwo = new Box();
	}

	//Tests Box's getters and setters.
	public void testGettersAndSetters() throws Throwable {
		//freezer getter and setter
		boxOne.setFreezer(boxOneFreezer);
		boxTwo.setFreezer(boxTwoFreezer);
		assertEquals(boxOne.getFreezer(), boxOneFreezer);
		assertEquals(boxTwo.getFreezer(), boxTwoFreezer);
		assertNotSame(boxOne.getFreezer(), boxTwo.getFreezer());

		//shelf getter and setter
		boxOne.setShelf(boxOneShelf);
		boxTwo.setShelf(boxTwoShelf);
		assertEquals(boxOne.getShelf(), boxOneShelf);
		assertEquals(boxTwo.getShelf(), boxTwoShelf);
		assertNotSame(boxOne.getShelf(), boxTwo.getShelf());

		//boxId setter. We must bypass the private restriction.
		Method method = Box.class.getDeclaredMethod(
				"setBoxId", long.class);
		method.setAccessible(true);
		method.invoke(boxOne, 1);
		//sampleId getter.
		assertEquals(boxOne.getBoxId(), 1);
	}

	public void testSampleHandling() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		Place  place = new Place (1,1, boxOne);
		Method insert = Box.class.getDeclaredMethod(
				"insertSample", Sample.class, Place.class);
		insert.setAccessible(true);
		Method remove = Box.class.getDeclaredMethod(
				"removeSample", Sample.class);
		remove.setAccessible(true);

		assertFalse(boxOne.contains(sampleOne));
		//assertFalse(boxOne.equals(sampleOne.getPlacement().getBox()));
		insert.invoke(boxOne, sampleOne, place);
		assertTrue(boxOne.contains(sampleOne));
		//assertFalse(boxOne.equals(sampleOne.getPlacement().getBox()));
		remove.invoke(boxOne, sampleOne);
		assertFalse(boxOne.contains(sampleOne));
	}
}
